package com.ebs.md.fxmonitor.marketmonitor.alert;

/**
 * Perforce Revision:
 *  $File: //depot/MarketData/fxmonitor/main/src/main/java/com/ebs/md/fxmonitor/marketmonitor/alert/AbstractAlertMessageCreator.java $
 *  $Revision: #6 $  $Change: 115093 $  $DateTime: 2012/09/20 16:21:00 $  $Author: Arik.Sher $
 */

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;

import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.apache.log4j.Logger;
import org.springframework.util.Assert;

import com.ebs.market.monitor.MarketMonitor.EventType;
import com.ebs.market.monitor.jms.MarketMonitorJmsConsts;
import com.ebs.md.fxmonitor.marketmonitor.MarketMonitorConsts;

/**
 * AbstractAlertMessageCreator should close the gap between GoogleProtocolBuffer and Internal model/domain data.
 *  and act as adapter.
 * 
 * TODO: should replace the existing AbstractEventMessageCreator.
 *       or AbstractEventMessageCreator should use this one where the DATA is parsed payload.
 * 
 * @param <GPB>  output GoogleProtocolBuffer type
 * @param <DATA> Type Of Serializable input
 */
public abstract class AbstractAlertMessageCreator<GPB extends com.google.protobuf.Message, DATA extends Serializable>
implements IAlertMessageCreator<GPB>
          ,MarketMonitorJmsConsts
          ,MarketMonitorConsts
{
    final protected Logger logger = Logger.getLogger(getClass());

	protected final long        eventTimeMillis;
	protected final List<DATA>  dataList;
	
	public AbstractAlertMessageCreator(List<DATA> dataList) {
		super();
		Assert.notEmpty(dataList, "'dataList' cannot be empty");
		this.eventTimeMillis = System.currentTimeMillis();
		this.dataList = dataList;
	}
	
	public AbstractAlertMessageCreator(DATA dataItem) {
		this(Arrays.asList(dataItem));
	}

	protected DATA getFirstDataElement() {
		return dataList.get(0);
	}
	
	public Message createMessage(Session session) throws JMSException {
		GPB eventObj = createAlertObject();
		
		BytesMessage jmsMessage = session.createBytesMessage();
		jmsMessage.writeBytes(eventObj.toByteArray());
		
		appendProperties(jmsMessage);
		
		jmsMessage.reset();
		return jmsMessage;
	}

	protected void appendProperties(Message jmsMessage) throws JMSException {
		jmsMessage.setIntProperty(   JMS_MSG_PROPERTY_EVENT_TYPE
				, getEventType().getNumber());

		doAppendExtraProperties(jmsMessage);
	}
	
	protected void doAppendExtraProperties(Message jmsMessage) throws JMSException {
		// nothing here, this method is used for override... 
	}

	final protected static TimeZone gmtTZ = TimeZone.getTimeZone("GMT");
	
	/**
	 * 
	 * @param millis since 1970
	 * @return "yyyymmdd"
	 */
	protected static String truncateToDate(long millis) {
		final Calendar cal = Calendar.getInstance(gmtTZ);
		cal.setTimeInMillis(millis);
		
//		final Calendar truncated = DateUtils.truncate(cal, Calendar.DAY_OF_MONTH);
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		sdf.setTimeZone(gmtTZ);
		
		return sdf.format(cal.getTime());
	}

	abstract public GPB createAlertObject();

	abstract public EventType getEventType();
	
}
